package org.agile4j.rpc.registry.zookeeper;

import org.I0Itec.zkclient.ZkClient;
import org.agile4j.rpc.common.utils.PropsUtil;
import org.agile4j.rpc.registry.ServiceRegistry;
import org.agile4j.rpc.registry.zookeeper.constant.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 基于 ZooKeeper 的服务注册接口实现
 *
 * Created by Administrator on 2016/8/12.
 */
public class ZooKeeperServiceRegistry implements ServiceRegistry {
    private static final Logger LOGGER = LoggerFactory.getLogger(ZooKeeperServiceRegistry.class) ;

    private ZkClient zkClient ;

    public ZooKeeperServiceRegistry(String zkAddress) {
        // 创建 ZooKeeper 客户端
        zkClient = new ZkClient(zkAddress, Constant.ZK_SESSION_TIMEOUT, Constant.ZK_CONNECTION_TIMEOUT) ;
        LOGGER.debug("connect zookeeper");
    }

    @Override
    public void register(String serviceName, String serviceAddress) {
        // 创建 registry 节点（持久）
        String registryPath = Constant.ZK_REGISTRY_PATH ;
        if (!zkClient.exists(registryPath)) {
            zkClient.createPersistent(registryPath); // 持久
            LOGGER.debug("create registry node: {}", registryPath);
        }
        // 创建 service 节点（持久）
        String servicePath = registryPath + "/" + serviceName ;
        if (!zkClient.exists(servicePath)) {
            zkClient.createPersistent(servicePath) ;
            LOGGER.debug("create service node: {}", servicePath);
        }
        
        // 创建 address 节点带序列（临时）, 并把serviceAddress 设置成 节点 data
        String addressPath = servicePath + "/address-" ;
        String addressNode = zkClient.createEphemeralSequential(addressPath, serviceAddress) ;
        LOGGER.debug("create address node: {}", addressNode);
        
        boolean flag = PropsUtil.getBoolean(PropsUtil.loadProps(Constant.RPC_SERVER_PROPES), Constant.ZK_WATCHE, false);
        if (flag) { // 是否监控直接点变化
        	zkClient.subscribeChildChanges(addressNode, new ZookeeperChildListener()) ;
		}
    }
}
